#include "MysqlConn.h"
#include "exception/SQLException.h"

using namespace std;
using namespace chrono;
using namespace mysql;

MysqlConn::MysqlConn() {
    conn_ = mysql_init(nullptr);
    if (conn_ == nullptr) {
        throw SQLException("Mysql init failed", mysql_errno(conn_), mysql_sqlstate(conn_));
    }
}

MysqlConn::~MysqlConn() {
    if (conn_ != nullptr)
        mysql_close(conn_);
}

void MysqlConn::connect(const string &user, const string &password, const string &dbname,
                        const string &ip, const unsigned short &port) {
    if (mysql_real_connect(conn_, ip.c_str(), user.c_str(), password.c_str(), dbname.c_str(), port, nullptr, 0) ==
        nullptr) {
        throw SQLException("MySQL connect failed", mysql_errno(conn_), mysql_error(conn_));
    }
}

void MysqlConn::setCharacterSet(const string &character_set) {
    if (mysql_set_character_set(conn_, character_set.c_str()) != 0) {
        throw SQLException("MySQL character set failed", mysql_errno(conn_), mysql_error(conn_));
    }
}

shared_ptr<MysqlStatement> MysqlConn::statement() {
    return make_shared<MysqlStatement>(conn_);
}

shared_ptr<MysqlPreparedStatement> MysqlConn::prepareStatement(const string &sql) {
    return make_shared<MysqlPreparedStatement>(conn_, sql);
}

void MysqlConn::refreshAliveTime() {
    alive_time_ = steady_clock::now();
}

long long MysqlConn::getAliveTime() {
    nanoseconds res = steady_clock::now() - alive_time_;
    milliseconds milli_seconds = duration_cast<milliseconds>(res);
    return milli_seconds.count();
}
